package com.yy.invoice.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yy.invoice.config.BaiDuConfig;
import com.yy.invoice.config.QiuNiuYunConfig;
import com.yy.invoice.entity.*;
import com.yy.invoice.mapper.InvoiceMapper;
import com.yy.invoice.mapper.UserMapper;
import com.yy.invoice.service.FileService;
import com.yy.invoice.utils.BaiDuApiUtils;
import com.yy.invoice.utils.FileUtils;
import com.yy.invoice.utils.JwtUtil;
import com.yy.invoice.utils.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class FileServiceImpl implements FileService {

    private static String basePath = System.getProperty("user.dir") + File.separator + "temp";

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private QiuNiuYunConfig qiuNiuYunConfig;

    @Autowired
    private BaiDuConfig baiDuConfig;

    @Autowired
    private RedisCache redisCache;

    @Override
    public Result upload(MultipartFile[] files, String month, HttpServletRequest request) {
        String token = request.getHeader("token");
        Result result = new Result();
        try {
            String userId = JwtUtil.parseJWT(token).getSubject();
            for (MultipartFile file : files) {
                String md5 = DigestUtils.md5DigestAsHex(file.getInputStream());
                //查询这张发票是否上传
                Invoice invoiceTest = invoiceMapper.selectOne(
                        new LambdaQueryWrapper<Invoice>()
                                .eq(Invoice::getUserId, userId)
                                .eq(Invoice::getMd5, md5)
                );
                //如果没有上传过就进行文件上传
                if (ObjectUtils.isEmpty(invoiceTest) || invoiceTest == null) {
                    File basePath = new File(FileServiceImpl.basePath);
                    if (!basePath.exists()) {
                        basePath.mkdir();
                    }
                    String path = FileServiceImpl.basePath + File.separator + file.getOriginalFilename();
                    file.transferTo(new File(path));
                    //执行上传文件
                    String upload = FileUtils.fileUpload(
                            file,
                            qiuNiuYunConfig.getAccessKey(),
                            qiuNiuYunConfig.getSecretKey(),
                            qiuNiuYunConfig.getBucket(),
                            qiuNiuYunConfig.getFileUrl()
                    );
                    //对文件进行识别
                    Invoice invoice = BaiDuApiUtils.vatInvoice(
                            path,
                            baiDuConfig.getAppId(),
                            baiDuConfig.getApiKey(),
                            baiDuConfig.getSecretKey()
                    );
                    //将本地缓存的文件删除
                    new File(path).delete();
                    //存入数据库
                    invoice.setUserId(userId);
                    invoice.setMd5(md5);
                    invoice.setPath(upload);
                    invoice.setUploadTime(month);
                    invoiceMapper.insert(invoice);
                }
            }
            result.setCode(0);
            result.setMessage("success");
        } catch (Exception e) {
            result.setCode(1);
            result.setMessage("error");
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public Result toExcel(List<Invoice> invoices, HttpServletRequest request) {
        Result result = new Result();
        try {
            List<List<String>> data = new ArrayList<>();
            String userId = JwtUtil.parseJWT(request.getHeader("token")).getSubject();
            String username = userMapper.selectOne(
                    new QueryWrapper<User>()
                            .eq("user_id", userId)
            ).getUsername();
            for (Invoice invoice : invoices) {
                List<String> item = new ArrayList<>();
                item.add(invoice.getInvoiceCode());
                item.add(invoice.getInvoiceNum());
                item.add(invoice.getInvoiceDate());
                item.add(invoice.getValidate());
                item.add(invoice.getTotalAmount());
                log.info("item:{}", item);
                data.add(item);
            }
            String filePath = basePath + "公务费-" + username + ".xlsx";
            EasyExcel.write(filePath, InvoiceExcel.class).sheet("公务费-" + username).doWrite(data);
            String excel = FileUtils.fileUpload(
                    new File(filePath),
                    qiuNiuYunConfig.getAccessKey(),
                    qiuNiuYunConfig.getSecretKey(),
                    qiuNiuYunConfig.getBucket(),
                    qiuNiuYunConfig.getFileUrl()
            );
            //上传成功之后将文件删除
            boolean delete = new File(filePath).delete();
            log.info("文件是否删除:" + delete);
            HashMap<String, String> map = new HashMap<>();
            map.put("excel", excel);
            result.setMessage("toExcel success");
            result.setData(map);
            result.setCode(0);
        } catch (Exception e) {
            result.setCode(1);
            result.setMessage("toExcel error");
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public Result pdfs2Pdf(List<Invoice> invoices, HttpServletRequest request) {
        Result result = new Result();
        try {
            String userId = JwtUtil.parseJWT(request.getHeader("token")).getSubject();
            String tempDir = System.getProperty("user.dir") + File.separator + "temp";
            File file = new File(tempDir);
            if (!file.exists()) {
                file.mkdir();
            }
            for (Invoice invoice : invoices) {
                FileUtils.downloadFile(invoice.getPath(), tempDir + File.separator + invoice.getMd5() + ".pdf");
                System.out.println(tempDir + File.separator + invoice.getMd5() + ".pdf");
            }
            String username = userMapper.selectOne(new QueryWrapper<User>().eq("user_id", userId)).getUsername();
            FileUtils.MulFileToOne(file.listFiles(), tempDir + File.separator + "公务费-" + username + ".pdf");
            String pdfs = FileUtils.fileUpload(
                    new File(tempDir + File.separator + "公务费-" + username + ".pdf"),
                    qiuNiuYunConfig.getAccessKey(),
                    qiuNiuYunConfig.getSecretKey(),
                    qiuNiuYunConfig.getBucket(),
                    qiuNiuYunConfig.getFileUrl()
            );
            log.info("pds：" + pdfs);
            //删除临时文件夹中的所有文件
            for (File listFile : file.listFiles()) {
                listFile.delete();
            }
            result.setCode(0);
            result.setMessage("pdfs2pdf success");
            HashMap<String, String> data = new HashMap<>();
            data.put("pdfs", pdfs);
            result.setData(data);
        } catch (Exception e) {
            result.setCode(1);
            result.setMessage("pdfs2pdf error");
            throw new RuntimeException(e);
        }
        return result;
    }

    @Override
    public Result getZip(List<Invoice> invoices, HttpServletRequest request) {
        Result result = new Result();
        try {
            String userId = JwtUtil.parseJWT(request.getHeader("token")).getSubject();
            LoginUser loginUser = redisCache.getCacheObject("login:" + userId);
            User user = loginUser.getUser();
            String pdfBasePath = basePath + File.separator + user.getUsername() + File.separator + "pdf";
            String zipBasePath = basePath + File.separator + user.getUsername() + File.separator + "zip";
            myMkdirs(pdfBasePath);
            myMkdirs(zipBasePath);
            String month = null;
            for (int i = 0; i < invoices.size(); i++) {
                int j = i + 1;
                String urlPath = invoices.get(i).getPath();
                String pdfPath = pdfBasePath + File.separator + user.getUsername() + "-发票" + j + "-" + invoices.get(i).getTotalAmount() + ".pdf";
                log.info("pdfPath:{}", pdfPath);
                //yang1yu-发票1-totalamount
                FileUtils.downloadFile(urlPath, pdfPath);
                if (i == invoices.size() - 1) {
                    month = invoices.get(i).getUploadTime().replace("-", "");
                }
            }
//            yang1yu-202210
            String zipPath = zipBasePath + File.separator + user.getUsername() + "-" + month + ".zip";
            ZipUtil.zip(pdfBasePath, zipPath);
            String upload = FileUtils.fileUpload(
                    new File(zipPath),
                    qiuNiuYunConfig.getAccessKey(),
                    qiuNiuYunConfig.getSecretKey(),
                    qiuNiuYunConfig.getBucket(),
                    qiuNiuYunConfig.getFileUrl()
            );
            log.info("zipPath:{}",upload);
            FileUtil.del(basePath);
            result.setCode(0);
            result.setMessage("zip success");
            result.setData(upload);
        } catch (Exception e) {
            result.setCode(1);
            result.setMessage("zip error");
            e.printStackTrace();
        }
        return result;
    }

    private void myMkdirs(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
    }
}
